;;; $Id: ao.sld 397 2014-02-19 21:14:46Z alan.watson.f $

(define-library (oaxaca ao)

  (export determine-i-matrix!)

  (import (scheme base)
          (scheme write))

  (import (oaxaca file)
          (oaxaca log)
          (oaxaca wfc))

  (begin

    (define (determine-i-matrix! n 
                                 directory-path
                                 da
                                 search-radius
                                 detector-search-radius
                                 detector-set-search-radius!
                                 refinement-radius
                                 detector-refinement-radius
                                 detector-set-refinement-radius!
                                 detector-expose!
                                 detector-wait
                                 detector-refine-spots!
                                 detector-s-vector)

      (define integration-time  1.0)
      (define exposure-time     3.0)

      (define saved-search-radius (detector-search-radius))
      (define saved-refinement-radius (detector-refinement-radius))

      (define (determine-s-vector irow da)
        (wfc-flatten!)
        (detector-expose! integration-time exposure-time)
        (detector-wait)
        (let ((a (wfc-a-vector)))
          (vector-set! a irow (+ (vector-ref a irow) da))
          (wfc-set-a-vector! a))
        (detector-expose! integration-time exposure-time)
        (detector-wait)
        (detector-refine-spots!)
        (detector-s-vector))

      (define (determine-i-matrix-row irow da)
        (vector-map
         (lambda (p q)
           (/ (- p q) 2 da))
         (determine-s-vector irow (+ da))
         (determine-s-vector irow (- da))))

      (define (determine-mean-i-matrix-row irow da n)
        (apply vector-map
               (lambda x-list
                 (/ (apply + x-list) n))
               (map
                (lambda args (determine-i-matrix-row irow da))
                (make-list n))))

      (detector-set-search-radius! search-radius)
      (detector-set-refinement-radius! refinement-radius)

      (let ((file-path (make-path directory-path "i-matrix")))
        (log-info "writing the i-matrix to \"" file-path "\".")
        (with-output-to-file file-path
          (lambda ()
            (display "#(\n")
            (do ((i 0 (+ i 1)))
                ((= i (vector-length da)))
              (log-info "mode " i ".")
              (display (determine-mean-i-matrix-row i (vector-ref da i) n))
              (newline))
            (display ")\n"))))

      (wfc-flatten!)
      (detector-expose! integration-time exposure-time)
      (detector-wait)

      (detector-set-search-radius! saved-search-radius)
      (detector-set-refinement-radius! saved-refinement-radius)

      (log-info "done.")

      (values))))
